/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package dtd.to.xml;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * Class Doctype_parser
 * This class contains methods to get 
 * root element
 * and also
 * path for extern DTD  
 * from loaded XML document.
 *
 * @version 1.0
 * @author Mato Majdis
 */
public class DoctypeParser {
    
    private String XMLPath;
    
    private Document doc = null;
    
    /**
     * Constructor for Class Doctype_parser
     * Initialize document parser
     * 
     * @param XMLPath path to XML document 
    */
    public DoctypeParser(String XMLPath){
        this.XMLPath = XMLPath;
        this.setDocument();
    }

    /**
     * Returns input path
     * 
     * @return path of input XML file
     */
    public String getXMLPath() {
        return XMLPath;
    }

    /**
     * Sets XMLPath needed for choosing input document
     * 
     * @param XMLPath Path for input document
     */
    public void setXMLPath(String XMLPath) {
        this.XMLPath = XMLPath;
    }

    /**
     * Returns document
     * 
     * @return Input document
     */
    public Document getDoc() {
        return doc;
    }

    /**
     * Sets document if it is needed
     * 
     * @param doc 
     */
    public void setDoc(Document doc) {
        this.doc = doc;
    }
    
    /**
     * Sets document parser
     * If initialization is not successful prints error message
    */
    private void setDocument(){
        try {
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            this.doc = docBuilder.parse (new File(XMLPath));
        } catch (SAXException e) {
            System.err.println("Error while parsing XML: " + e.getMessage());
                    } catch (ParserConfigurationException | IOException ex) {
            System.err.println("Error while parsing XML: " + ex.getMessage());
        }
    }
    
    /**
     * Returns name of root element of parsed XML
     * 
     * @return name of root element if XML document was successfully parsed
     *         null otherwise
     */
    public String getRootName(){
        String rootName = null;
        
        if(doc != null){
            rootName = doc.getDoctype().getName();
        }
        
        return rootName;
    }
    
    /**
     * Returns path to extern DTD for XML document
     * If XML has extern DTD returns its path
     * If XML has intern DTD returns "temporary.dtd" file which
     * contains interns DTD restrictions
     * If XML parsing failed returns null
     * 
     * @return path to extern DTD if XML has extern DTD
     *         path to created "temporary.dtd" if XML has intern DTD
     *         null otherwise
     */
    public String getDTDLink(){
        String link = null;
        
        if(doc != null){
            String parsedLink = doc.getDoctype().getSystemId();
            if(parsedLink != null){
                if(System.getProperty("os.name").equals("Linux"))
                    link = "/" + parsedLink.substring(6);
                else
                    link = parsedLink.substring(6);
            } else {
                link = createTempFile();
            }
        }
        
        return link;
    }
    
    /**
     * Creates "temporary.dtd" file with intern DTDs restrictions
     * 
     * @return link to created file if was succesfully created
     *         null otherwise
     */
    private String createTempFile() {
        String link = null;
        
        try(FileWriter fw = new FileWriter("temporary.dtd");
            PrintWriter out = new PrintWriter(fw))  {
            
            out.println("<?xml version='1.0' encoding='UTF-8'?>");
            out.println(doc.getDoctype().getInternalSubset());
            
            link = "temporary.dtd";
            
            fw.close();
            out.close();
        } catch (IOException ex) {
            System.out.println("Interna error: " + ex.getMessage());
        }
               
        return link;
    }
}
